﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using DotNetty.Codecs.Http;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using ME860.DotNetty.Common;
using ME860.DotNetty.Server.Core;

namespace ME860.DotNetty.Server.CoreImpl
{
    class DotNettyServerImpl : IDotNettyServer
    {
        public event Action<string> OnMessage;
        public event Action<string, string> OnSubMessage;
        public event Action<Exception> OnException;
        public event Func<string> OnGetCommand;
        public async Task RunServerAsync()
        {

            OnSubMessage?.Invoke("服务启动中......", "重要");
            //1.创建ServerBootstrap实例
            var bootstrap = new ServerBootstrap();
            //2:绑定事件组
            IEventLoopGroup mianGroup = new MultithreadEventLoopGroup();
            IEventLoopGroup workGroup = new MultithreadEventLoopGroup();
            bootstrap.Group(mianGroup, workGroup);
            //3.绑定通道
            bootstrap.Channel<TcpServerSocketChannel>();
            //4.配置处理器
            bootstrap.ChildHandler(new ActionChannelInitializer<IChannel>(channel =>
            {
                var pipeline = channel.Pipeline;
                pipeline.AddLast(new HttpServerCodec());
                pipeline.AddLast(new HttpObjectAggregator(65536));
                pipeline.AddLast(new ChannelHandler());
            }));
            //5.配置主机和端口号
            string hostName = Dns.GetHostName();
            var ipAddresses = Dns.GetHostAddresses(hostName);
            ipAddresses = ipAddresses.Where(m => m.ToString().IsIPv4()).ToArray();
            var trueAddress = ipAddresses.Any(m => ApplicationConfig.ServerConfig.Host.Equals(m.ToString()));
            var ipAddress =
                trueAddress ? IPAddress.Parse(ApplicationConfig.ServerConfig.Host) : ipAddresses[0];
            var bootstrapChannel = await bootstrap.BindAsync(ipAddress, ApplicationConfig.ServerConfig.Port);

            OnSubMessage?.Invoke("服务启动成功", "重要");
            OnMessage?.Invoke($"已监听http://{ipAddress}:{ApplicationConfig.ServerConfig.Port}");
            //6.停止服务
            OnMessage?.Invoke("输入Stop停止服务");
            var inputkey = string.Empty;
            while (!inputkey.Equals("Stop", StringComparison.Ordinal))
            {
                inputkey = OnGetCommand?.Invoke();
                if (!string.Equals(inputkey, "Stop", StringComparison.Ordinal))
                {
                    OnException?.Invoke(new DotNettyServerException("未识别命令请重新输入"));
                }
            }
            OnSubMessage?.Invoke("正在停止服务", "重要");
            await bootstrapChannel.CloseAsync();
            OnSubMessage?.Invoke("服务已停止", "重要");

        }
    }
}
